package com.tech.zhidengxian.websocket;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import com.tech.zhidengxian.model.dto.WebSocketMessageDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;

import javax.annotation.Resource;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @param
 * @author Ljh
 * @date 2022/8/1 10:03
 * @description springboot的websocket实现方式
 * @return
 **/
@Component
@Slf4j
public class IMWebsocketHandler extends AbstractWebSocketHandler {
    private ConcurrentMap<Long, WebSocketSession> onlineUser=new ConcurrentHashMap<>();

    private static MessageHandler messageHandler;

    @Resource
    public void setMessageHandler(MessageHandler messageHandler) {
        IMWebsocketHandler.messageHandler = messageHandler;
    }


    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        log.info("连接上线");
        String url = session.getUri().toString();
        String userId = url.substring(url.lastIndexOf("=")+1);
        onlineUser.put(Long.valueOf(userId), session);
//        session.getHandshakeHeaders()
        session.setBinaryMessageSizeLimit(1024*512);
        session.setTextMessageSizeLimit(1024*512);
    }

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        String msg = message.getPayload().toString();
        WebSocketMessageDTO webSocketMessageDTO = JSON.parseObject(msg, WebSocketMessageDTO.class);
        Map<Long, WebSocketMessageDTO> map = messageHandler.handlerMessage(webSocketMessageDTO);
        map.keySet().forEach(key->{
            WebSocketSession webSocketSession = onlineUser.get(key);
            if (webSocketSession!=null){
                WebSocketMessageDTO messageDTO = map.get(key);
                sendMessage(JSON.toJSONString(messageDTO),webSocketSession);
            }
        });
    }

    /**
    *@author Ljh
    *@params [session, message]
    *@date 2022/8/9 14:34
    *@description 文件类型消息两种思路
     * 1.使用ws传输，buffer类型二进制数据，上传服务器后向收发方发送描述信息
     * 2.使用http传输上传服务器，完成后调用ws向收发方发送描述信息
     * 3.均服务端存储，仅描述信息落库
    *@return void
    **/
    @Override
    protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
        log.info("二进制信息");
        ByteBuffer payload = message.getPayload();
        super.handleBinaryMessage(session, message);
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        log.info("连接出错");

    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        String url = session.getUri().toString();
        String userId = url.substring(url.lastIndexOf("=")+1);
        onlineUser.remove(userId);
        log.info("连接已关闭,status:" + closeStatus);

    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    private void sendMessage(String message,WebSocketSession session){
        try {
            session.sendMessage(new TextMessage(message));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
